home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
1833
/
1833.xpi
/
chrome
/
yoono.jar
/
ff2
/
bookmarks.js
< prev
Wrap
Text File
|
2009-12-16
|
14KB
|
446 lines
var CI = Components.interfaces;
var CL = Components.classes;
const RDF = CL["@mozilla.org/rdf/rdf-service;1"].getService(CI.nsIRDFService);
const ROOTNODE = RDF.GetResource('NC:BookmarksRoot');
var gDataSource = RDF.GetDataSource("rdf:bookmarks").QueryInterface(CI.nsIBookmarksService);
const RDFC = CL["@mozilla.org/rdf/container;1"];
const LASTMODIFIED_RESOURCE = RDF.GetResource("http://home.netscape.com/Web-esd#LastModifiedDate");
function start(launch) {
var _this=this;
var timer = CL['@mozilla.org/timer;1'].createInstance(CI.nsITimer);
var callback = {
notify : function() {
try {
if (!gDataSource.GetTarget(RDF.GetResource('NC:BookmarksRoot'), NAME_RESOURCE, true)) {
log.error("Delay bookmarks loading because of RDF :X");
return timer.initWithCallback(callback, 1000 , timer.TYPE_ONE_SHOT);
}
gCurrentTree = new bkmNode('NC:BookmarksRoot', null, true);
gToolbarNode = gBkmById[rdfUtils.getValue(gDataSource.getBookmarksToolbarFolder())];
// TODO : do not set bkm change observer if non-yet created user
//log.error("BKM CHANGE OBSERVER DISABLED DURING WIZARD TESTS");
gDataSource.AddObserver(BkmsObserverFF2.rdfObserver);
launch();
} catch(e) {
log.exception(e);
}
}
};
callback.notify();
}
var gBrowserBkm = {
runInBatchMode : function (process) {
gDataSource.beginUpdateBatch();
try {
process();
} catch(e) {
log.exception(e);
}
gDataSource.endUpdateBatch();
},
createBookmark : function ( title, url, parent) {
log.debug(" create bookmark = title:"+title+" url:"+url+" parentId:"+parent.getId());
var res = gDataSource.createBookmarkInContainer (title, url, '', '', '', null, parent.resource, null);
return BkmsObserver.onItemAdded(rdfUtils.getValue(res),parent.getId(),-1);
},
createLivemark : function ( title, url, parent) {
log.debug(" create livemark = title:"+title+" url:"+url+" parentId:"+parent.getId());
var res = gDataSource.createLivemarkInContainer (title, '', url, '', parent.resource, null);
return BkmsObserver.onItemAdded(rdfUtils.getValue(res),parent.getId(),-1);
},
create : function (node, parent) {
log.debug(" create from node = nodeId:"+node+" parentId:"+parent.getId());
if (node.isLive())
return this.createLivemark(node.getName(),node.getUrl(),node.getParent());
return this.createBookmark(node.getName(),node.getUrl(),node.getParent());
},
createFolder : function (name, parent) {
log.debug(" create folder = title:"+name+" parentId:"+parent.getId());
var res = gDataSource.createFolderInContainer(name, parent.resource, 0);
return BkmsObserver.onItemAdded(rdfUtils.getValue(res),parent.getId(),-1);
},
rename : function (node) {
var oldName = gDataSource.GetTarget(node.resource, NAME_RESOURCE, true);
log.debug(" rename nodeId:"+node.getId()+" title:"+node.getName()+" res:"+node.resource+" oldName:"+oldName);
if (oldName)
gDataSource.Change(node.resource, NAME_RESOURCE, oldName, RDF.GetLiteral(node.getName()));
else
gDataSource.Assert(node.resource, NAME_RESOURCE, RDF.GetLiteral(node.getName()),true);
return BkmsObserver.onItemChanged(node.getId(),"uri",null,null);
},
remove : function (node) {
log.debug(" remove bookmark nodeId:"+node.getId());
var parent = node.getParent();
var res = node.resource;
var container = RDFC.createInstance(CI.nsIRDFContainer);
container.Init(gDataSource, parent.resource);
container.RemoveElement(res, false);
// unassert
var props=gDataSource.ArcLabelsOut(res);
while(props.hasMoreElements()) {
var prop=props.getNext();
var target=gDataSource.GetTarget(res,prop,true);
gDataSource.Unassert(res,prop,target);
}
return BkmsObserver.onItemRemoved(rdfUtils.getValue(res),parent.getId(),-1);
}
}
////////////////////////////
// BkmsObserver
// :: observe RDF modifications
// :: init sync system
const OBSERVER_DELAY = 2000; // en ms. Aggregation des evenements d'une manip utilisateur
var BkmsObserverFF2 = {
_timerInProgress : false,
_nodeTreeCreated : false,
rdfObserver : {
timer : CL['@mozilla.org/timer;1'].createInstance(CI.nsITimer),
launchTimer : function () {
if (!BkmsObserverFF2._timerInProgress && !Server2Browser.isWorking()) {
BkmsObserverFF2._timerInProgress = true;
this.timer.initWithCallback(BkmsObserverFF2, OBSERVER_DELAY, this.timer.TYPE_ONE_SHOT);
}
},
onBeginUpdateBatch : function(ds) {
log.debug("BkmsObserver onBeginUpdateBatch");
},
onEndUpdateBatch : function(ds) {
log.debug("BkmsObserver onEndUpdateBatch");
this.launchTimer();
},
onAssert : function(ds, source, predicate, target) {
//log.debug("BkmsObserver onAssert");
//if (predicate == LASTMODIFIED_RESOURCE)
this.launchTimer();
},
onUnassert : function(ds, source, predicate, target) {
//log.debug("BkmsObserver onUnassert");
//if (predicate == LASTMODIFIED_RESOURCE)
this.launchTimer();
},
onChange : function(ds, source, predicate, oldTarget, newTarget) {
//log.debug("BkmsObserver onChange");
//if (predicate == LASTMODIFIED_RESOURCE)
this.launchTimer();
},
onMove : function(ds, oldSource, newSource, predicate, target) {
log.debug("BkmsObserver onMove");
},
},
notify : function(subject, topic, data) {
try {
changesMgr.updateTree();
this._timerInProgress = false;
} catch(e) {
log.exception(e);
}
},
forceUpdate : function () {
try {this.timer.cancel();} catch(e) {}
changesMgr.updateTree();
}
};
//////////////////////////////
////////////////////////////////////
// changesMgr
// :: Parse bookmarks tree (gCurrentTree) to detect user changes
var changesMgr = {
changeDetected: false, // flag to detect changes while updateTree is running
running: false, // flag to avoid requesting a sync while updateTree is running
updateTree : function () {
try {
if (!gCurrentTree)
return log.error("bookmarks not already loaded!!!");
var beginTst = new Date().getTime();
log.debug('begin updateTree');
this.changeDetected = false;
this.running = true;
for each (var node in gBkmById) {
node.seen = false;
}
var oldNb=yoono.bkm.bookmarksNumber();
this.traverseTree(RDF.GetResource('NC:BookmarksRoot'), null);
for each (var node in gBkmById) {
if (!node.seen)
BkmsObserver.onItemRemoved(node.getId(), node.getParent()?node.getParent().getId():null, -1);
}
log.debug('tree updated after : ' + (new Date().getTime() - beginTst) + 'ms');
if (oldNb!=yoono.bkm.bookmarksNumber())
yoono.bkm.dump();
this.running = false;
} catch(e) {
log.exception(e);
}
},
traverseTree : function (resource, parent) {
var node = gBkmById[resource.Value];
if (node) {
var name = rdfUtils.getName(resource);
if (resource==gDataSource.getBookmarksToolbarFolder())
name=TOOLBARNAME;
var url = rdfUtils.getUrl(resource);
var _haschanged = ( url != node.getUrl() || name != node.getName() );
var _hasmoved = parent != node.getParent();
if (node.isFolder()) {
var container = RDFC.createInstance(CI.nsIRDFContainer);
container.Init(gDataSource, resource);
var children = container.GetElements()
while (children.hasMoreElements()) {
var child=children.getNext();
if (rdfUtils.getType(child) != SEPARATOR_TYPE)
this.traverseTree(child, node);
}
}
if (_haschanged && node!=gCurrentTree) {// ignore changes of root node
log.debug("Changed : RES= "+rdfUtils.getName(node.resource)+" URL= '"+url+"' / '"+node.getUrl()+"' NAME= '"+name+"' / '"+node.getName()+"'");
if (url != node.getUrl())
BkmsObserver.onItemChanged(node.getId(), "uri", null, url);
if (name != node.getName())
BkmsObserver.onItemChanged(node.getId(), "title", null, name);
}
if (_hasmoved) {
log.debug("Moved : RES= "+rdfUtils.getName(node.resource)+" PARENT= '"+parent);
/*
+"' / '"+node.getParent()+"' NAME= '"+name+"' / '"+node.getName()+"'");
*/
BkmsObserver.onItemMoved(node.getId(), node.getParent().getId(), -1, parent.getId(), -1);
}
} else {
var parentNode = rdfUtils.getParent(resource);
node = BkmsObserver.onItemAdded(rdfUtils.getValue(resource), parentNode.getId(), -1);
// notify creation of all sub nodes and mark them as seen
if (node.isFolder()) {
var container = RDFC.createInstance(CI.nsIRDFContainer);
container.Init(gDataSource, resource);
var children = container.GetElements()
while (children.hasMoreElements()) {
var child=children.getNext();
if (rdfUtils.getType(child) != SEPARATOR_TYPE)
this.traverseTree(child, node);
}
}
}
//log.debug("Seen >> "+node.getId());
node.seen = true;
}
}
//////////////////////////////////////
const NAME_RESOURCE = RDF.GetResource("http://home.netscape.com/NC-rdf#Name");
const URL_RESOURCE = RDF.GetResource("http://home.netscape.com/NC-rdf#URL");
const FEED_URL_RESOURCE = RDF.GetResource("http://home.netscape.com/NC-rdf#FeedURL");
const TYPE_RESOURCE = RDF.GetResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
const TOOLBAR_FOLDER_RESOURCE = RDF.GetResource("http://home.netscape.com/NC-rdf#BookmarksToolbarFolder");
const ID_RESOURCE = RDF.GetResource("http://home.netscape.com/NC-rdf#ID");
const LINKSTRING_RESOURCE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#_";
const REGULAR_TYPE = "http://home.netscape.com/NC-rdf#Bookmark";
const SEPARATOR_TYPE = "http://home.netscape.com/NC-rdf#BookmarkSeparator";
const FOLDER_TYPE = "http://home.netscape.com/NC-rdf#Folder";
const LIVEBKM_TYPE = "http://home.netscape.com/NC-rdf#Livemark";
var rdfUtils = {
getValue : function (target) {
// resource
if( target instanceof CI.nsIRDFResource ) {
return target.Value;
// LitΘral
} else if( target instanceof CI.nsIRDFLiteral ) {
return target.Value;
// Date
} else if( target instanceof CI.nsIRDFDate ) {
return target.Value;
// Int
} else if( target instanceof CI.nsIRDFInt ) {
return target.Value;
} else {
return ":blob";
}
},
/*
@param source : une resource RDF
@return : un noeud de l'arborescence
*/
getParent: function (resource) {
function beginsWith(str,substr) {
return (str.slice(0, substr.length) == substr);
}
if (resource == ROOTNODE)
return null;
var predicates = gDataSource.ArcLabelsIn(resource);
while (predicates.hasMoreElements()) {
var predicate = predicates.getNext();
if (predicate instanceof CI.nsIRDFResource
&& beginsWith(predicate.Value,LINKSTRING_RESOURCE)) {
return gBkmById[rdfUtils.getValue(gDataSource.GetSource(predicate, resource, true))];
}
}
// pas de parent
return null;
},
getName: function(resource) {
var nameRes = gDataSource.GetTarget(resource, NAME_RESOURCE, true);
if( nameRes ) {
return nameRes.QueryInterface(CI.nsIRDFLiteral).Value;
} else {
return "";
}
},
getType : function (source) {
return rdfUtils.getValue(gDataSource.GetTarget(source, TYPE_RESOURCE, true));
},
/*
la source doit etre de type regular ou livebkm,
cela doit etre verifie avant d'appeler cette fonction
*/
getUrl : function (source) {
var urlRes = gDataSource.GetTarget(source, FEED_URL_RESOURCE, true);
// on utilse FeedUrl pour les live-bookmarks
if (urlRes && urlRes instanceof CI.nsIRDFLiteral ) {
var url = urlRes.Value;
// See ticket #613 about replacing "
return url ? url.replace(/"/g, '%22') : MAGIC_URL;
}
urlRes = gDataSource.GetTarget(source, URL_RESOURCE, true);
if( urlRes instanceof CI.nsIRDFLiteral) {
var url = urlRes.Value;
// See ticket #613 about replacing "
return url ? url.replace(/"/g, '%22') : MAGIC_URL;
}
}
};
function bkmNode(id, parent, autoCreate) {
this.id=id;
this.resource=RDF.GetResource(id);
this.childsList=[];
this.private=false;
gBkmById[id] = this;
this.update(parent);
if (autoCreate && this.isFolder()) {
var container = RDFC.createInstance(CI.nsIRDFContainer);
container.Init(gDataSource, this.resource);
var children = container.GetElements()
nbBkms -- ; // do not count folders
while (children.hasMoreElements()) {
var child=children.getNext();
if (rdfUtils.getType(child) != SEPARATOR_TYPE) {
nbBkms ++;
this.childsList.push(new bkmNode(rdfUtils.getValue(child), this, autoCreate));
}
}
}
}
// called on properties update
bkmNode.prototype.update = function (parent) {
var oldParent=this.parent, oldType=this.type, oldName=this.name, oldUrl=this.url;
this.parent=parent?parent:this.parent;
this.type=rdfUtils.getType(this.resource);
if (this.resource==gDataSource.getBookmarksToolbarFolder())
this.name=TOOLBARNAME;
else
this.name=rdfUtils.getName(this.resource);
this.url=rdfUtils.getUrl(this.resource);
this.path=false;
if (this.isBookmark() || this.isLive()) {
if (oldUrl)
delete gBkmByUrl[oldUrl];
gBkmByUrl[this.getUrl()] = this;
}
if (oldParent!=this.parent || (this.isFolder() && oldName!=this.name))
this.traverseNode({onNode:function(node){node.path=false}});
if (oldParent!=this.parent || oldType!=this.type || oldName!=this.name || oldUrl!=this.url) {
this.syncid=false;
this.path = false;
this.resetSyncid();
//log.debug("updated!");
return true;
}
//log.debug("NOT updated!");
return false;
}
bkmNode.prototype.isFolder = function () {
return (this.type==FOLDER_TYPE);
}
bkmNode.prototype.isBookmark = function () {
return (this.type==REGULAR_TYPE);
}
bkmNode.prototype.isLive = function () {
return (this.type==LIVEBKM_TYPE);
}